/**
 * Project: apollo-base-commons
 * 
 * File Created at 2016年10月25日
 * 
 * Copyright 2015-2016 dx.com Croporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * DongXue software Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with dx.com.
 */
package com.dx.pf.commons.async.pool;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.dx.pf.commons.async.bean.SyncResult;
import com.dx.pf.commons.async.core.AsyncFutureCallback;
import com.dx.pf.commons.async.core.AsyncProfiler;
import com.dx.pf.commons.log.Logger;

/** 
* @ClassName: AsyncThreadTaskPool 
* @Description: TODO(这里用一句话描述这个类的作用) 
* @author wuzhenfang(wzfbj2008@163.com)
* @date 2016年10月25日 下午3:54:03 
* @version V1.0 
*/
public class AsyncThreadTaskPool {

	private static Logger logger = Logger.getLogger(AsyncThreadTaskPool.class);

	private ThreadPoolExecutor threadPoolExecutor = null;

	public AsyncThreadTaskPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
		threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
	}

	public AsyncThreadTaskPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
		threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
	}

	public AsyncThreadTaskPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler,
			ThreadFactory threadFactory) {
		threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
	}

	public <T> AsyncFutureTask<T> submit(AsyncPoolCallable<T> task, AsyncFutureCallback<T> callback) {
		if (task == null)
			throw new NullPointerException();
		AsyncFutureTask<T> ftask = new AsyncFutureTask<T>(task, callback);
		if (AsyncProfiler.get().getNumber() >= threadPoolExecutor.getCorePoolSize()) {
			T t = null;
			SyncResult<T> sync = new SyncResult<T>();
			try {
				t = task.call();
				sync.setValue(t);
				if (callback != null) {
					callback.onSuccess(t);
				}
			} catch (Throwable e) {
				sync.setThrowable(e);
				if (callback != null) {
					callback.onFailure(e);
				}
			}
			ftask.setSync(sync);
			return ftask;
		}
		execute(ftask);
		return ftask;
	}

	public void execute(Runnable command) {
		threadPoolExecutor.execute(command);
	}

	public void destroy() {
		if (!threadPoolExecutor.isShutdown()) {
			threadPoolExecutor.shutdown();
			logger.info("AsyncThreadTaskPool destroy;ThreadPoolExecutor Info:" + threadPoolExecutor.toString());
			threadPoolExecutor = null;
		}
	}

	public ThreadPoolExecutor getThreadPoolExecutor() {
		return threadPoolExecutor;
	}
}
